package com.young.ums.util;

import com.young.common.util.CommonConstants;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * 文件系统客户端助手
 * Created by rookie on 2017/10/5.
 */
public class FsClientHelper {

    private static final Logger logger = LoggerFactory.getLogger(FsClientHelper.class);

    private static final int DEFAULT_CONNECT_TIMEOUT = 300000;
    private static final int DEFAULT_READ_TIMEOUT = 300000;

    /**
     * 发送文件(批量)
     * @param url
     * @param fileArr
     * @return
     */
    public static String sendFiles(String url, MultipartFile[] fileArr){
        //待传输文件集合
        HashMap<String, InputStream> files = new HashMap<String, InputStream>();
        for (MultipartFile file : fileArr){
            try {
                files.put(file.getOriginalFilename(), file.getInputStream());
            } catch (IOException e) {
                e.printStackTrace();
                logger.error("[传输文件] *异常 获取文件流出错!");
            }
        }
        return sendFiles(url, files);
    }

    /**
     * 传输文件流(批量)
     * @param url
     * @param files
     * @return
     */
    public static String sendFiles(String url, HashMap<String, InputStream> files){
        int connectTimeout=DEFAULT_CONNECT_TIMEOUT;
        int readTimeOut=DEFAULT_READ_TIMEOUT;
        HttpURLConnection httpCon = null;
        try {
            String BOUNDARY = "---------7d4a6d158c9"; // 定义数据分隔线
            URL connUrl  = new URL(url);
            httpCon = (HttpURLConnection) connUrl.openConnection();
            httpCon.setConnectTimeout(connectTimeout);
            httpCon.setReadTimeout(readTimeOut);
            httpCon.setDoOutput(true);
            httpCon.setDoInput(true);
            httpCon.setRequestMethod("POST");
            httpCon.setUseCaches(false);
            httpCon.setAllowUserInteraction(true);
            httpCon.setRequestProperty("Charset", CommonConstants.CHARSET);
            httpCon.setRequestProperty("X-Requested-With", "XMLHttpRequest");//模拟ajax请求
            httpCon.setRequestProperty("connection", "Keep-Alive");
            httpCon.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
            httpCon.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);

            httpCon.connect();


            OutputStream out = new DataOutputStream(httpCon.getOutputStream());
            try {
                byte[] end_data = ("\r\n--" + BOUNDARY + "--\r\n").getBytes();// 定义最后数据分隔线
                Iterator iter = files.entrySet().iterator();
                int i=0;
                while (iter.hasNext()) {
                    i++;
                    Map.Entry entry = (Map.Entry) iter.next();
                    String key = (String) entry.getKey();
                    InputStream val = (InputStream) entry.getValue();
                    String fname = key;
                    File file = new File(fname);
                    StringBuilder sb = new StringBuilder();
                    sb.append("--");
                    sb.append(BOUNDARY);
                    sb.append("\r\n");
                    sb.append("Content-Disposition: form-data;name=\"file" + i
                            + "\";filename=\"" + key + "\"\r\n");
                    sb.append("Content-Type:application/octet-stream\r\n\r\n");

                    byte[] data = sb.toString().getBytes();
                    out.write(data);
                    DataInputStream in = new DataInputStream(val);
                    int bytes = 0;
                    byte[] bufferOut = new byte[1024];
                    while ((bytes = in.read(bufferOut)) != -1) {
                        out.write(bufferOut, 0, bytes);
                    }
                    out.write("\r\n".getBytes()); // 多个文件时，二个文件之间加入这个
                    in.close();
                }
                out.write(end_data);
                out.flush();
                out.close();
            } finally {
                IOUtils.closeQuietly(out);
            }
            int rscode = httpCon.getResponseCode();
            if (rscode == 200)return readRequestData(httpCon.getInputStream());
            logger.error("HTTP请求没有正确返回,状态["+rscode+"]");
        }catch(Exception e){
            logger.error("HTTP请求异常",e);
        }finally {
            try{
                if (httpCon != null)httpCon.disconnect();
            }catch(Exception e){
                logger.error("关闭HTTP请求异常",e);
            }
        }
        return null;
    }

    /**
     * 读取request中的数据
     * @param is
     * @return
     * @throws Exception
     * @return String
     * @throws
     */
    private static String readRequestData(InputStream is){
        StringBuffer sb = new StringBuffer();
        BufferedReader br =null;
        InputStreamReader isr = null;
        try {
            isr = new InputStreamReader(is,CommonConstants.CHARSET);
            br = new BufferedReader(isr);
            String str = null;
            while ((str = br.readLine()) != null) {
                sb.append(str);
            }
            return sb.toString();
        } catch (Exception ioe) {
            logger.error("读取HTTP请求的返回消息异常", ioe);
        }finally{
            IOUtils.closeQuietly(br);
            IOUtils.closeQuietly(isr);
            IOUtils.closeQuietly(is);
        }
        return null;
    }
}
